package com.baijiayun.liveuibase.zxing;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.TypedValue;

import com.journeyapps.barcodescanner.ViewfinderView;

/**
 * Created by pengwenjian on 2020/11/11
 * Describe:二维码扫描方式
 */
public class CustomViewfinderView extends ViewfinderView {

    //重绘时间间隔
    private static final long CUSTOME_ANIMATION_DELAY = 10;
    //边角线长度/扫描边框长度"的占比 (比例越大，线越长)
    public float mLineRate = 0.1F;
    //边角线厚度
    public float mLineDepth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
    //边角线颜色
    public int mLineColor = 0xffeeeeee;
    //扫描线起始位置
    public float mScanLinePosition = 0.f;
    //扫描线厚度
    public float mScanLineDepth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, getResources().getDisplayMetrics());
    //扫描线每次重绘的移动距离
    public float mScanLineDy = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics());
    //线性梯度
    public LinearGradient mLinearGradient;
    //线性梯度各个位置对应的颜色值
    public int mScanLineColor = 0xff1795ff;
    public int[] mScanLineColors = new int[]{0x001795ff, 0xff1795ff, 0xff1795ff, 0x001795ff};
    public float[] mPosition = new float[]{0f, 0.25f, 0.75f, 1f};
    //网格线颜色 20%透明度
    public int mScaneGridColor = 0x331795ff;
    //网格线宽
    public float mGriddingLineWidth = 2;
    //网格线密度
    public int mGriddingDensity = 25;
    //网格线着色器
    public LinearGradient mLinearGradientGridding;
    //网格线画笔
    public Paint mGriddingPaint;
    //矩阵用于设置着色器
    public Matrix mScanMatrix;
    //网格path
    public Path mGriddingPath;
    //网格高度用于设置matrix
    public int mFrameHeight;
    //四周的线
    public Paint mFramePaint;

    public CustomViewfinderView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mScanMatrix = new Matrix();
        mGriddingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mGriddingPaint.setStyle(Paint.Style.STROKE);
        mGriddingPaint.setStrokeWidth(mGriddingLineWidth);

        mFramePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mFramePaint.setStyle(Paint.Style.STROKE);
        mFramePaint.setStrokeWidth(mGriddingLineWidth);
        mFramePaint.setColor(mScaneGridColor);
    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas) {
        refreshSizes();
        if (framingRect == null || previewFramingRect == null) {
            return;
        }
        initGridPath(framingRect);
        Rect frame = framingRect;
        //绘制4个角
        paint.setColor(mLineColor);
        canvas.drawRect(frame.left, frame.top, frame.left + frame.width() * mLineRate, frame.top + mLineDepth, paint);
        canvas.drawRect(frame.left, frame.top, frame.left + mLineDepth, frame.top + frame.height() * mLineRate, paint);

        canvas.drawRect(frame.right - frame.width() * mLineRate, frame.top, frame.right, frame.top + mLineDepth, paint);
        canvas.drawRect(frame.right - mLineDepth, frame.top, frame.right, frame.top + frame.height() * mLineRate, paint);

        canvas.drawRect(frame.left, frame.bottom - mLineDepth, frame.left + frame.width() * mLineRate, frame.bottom, paint);
        canvas.drawRect(frame.left, frame.bottom - frame.height() * mLineRate, frame.left + mLineDepth, frame.bottom, paint);

        canvas.drawRect(frame.right - frame.width() * mLineRate, frame.bottom - mLineDepth, frame.right, frame.bottom, paint);
        canvas.drawRect(frame.right - mLineDepth, frame.bottom - frame.height() * mLineRate, frame.right, frame.bottom, paint);

        //四周变暗
        @SuppressLint("CanvasSize") int width = canvas.getWidth();
        @SuppressLint("CanvasSize") int height = canvas.getHeight();
        paint.setColor(maskColor);
        canvas.drawRect(0, 0, width, frame.top, paint);
        canvas.drawRect(0, frame.top, frame.left, frame.bottom, paint);
        canvas.drawRect(frame.right, frame.top, width, frame.bottom, paint);
        canvas.drawRect(0, frame.bottom, width, height, paint);

        mScanLinePosition += mScanLineDy;
        if (mScanLinePosition > frame.height() - mScanLineDepth) {
            mScanLinePosition = 0;
        }
        paint.setColor(mScanLineColor);
        mLinearGradient = new LinearGradient(frame.left, frame.top + mScanLinePosition, frame.right, frame.top + mScanLinePosition + mScanLineDepth, mScanLineColors, mPosition, Shader.TileMode.CLAMP);
        paint.setShader(mLinearGradient);
        canvas.drawRect(frame.left, frame.top + mScanLinePosition, frame.right, frame.top + mScanLinePosition + mScanLineDepth, paint);
        paint.setShader(null);
        //绘制网格
        mScanMatrix.setTranslate(0, -mFrameHeight + mScanLinePosition);
        mLinearGradientGridding.setLocalMatrix(mScanMatrix);
        canvas.drawPath(mGriddingPath, mGriddingPaint);
        //四周边框网格线一直存在
        canvas.drawRect(frame.left, frame.top, frame.right, frame.bottom, mFramePaint);
        // Request another update at the animation interval, but only repaint the laser line,
        // not the entire viewfinder mask.

        postInvalidateDelayed(CUSTOME_ANIMATION_DELAY,
                frame.left,
                frame.top,
                frame.right,
                frame.bottom);
    }

    private void initGridPath(Rect framingRect) {
        if (mGriddingPath == null) {
            mGriddingPath = new Path();
            float wUnit = framingRect.width() / (mGriddingDensity + 0f);
            float hUnit = framingRect.height() / (mGriddingDensity + 0f);
            for (int i = 0; i <= mGriddingDensity; i++) {
                mGriddingPath.moveTo(framingRect.left + i * wUnit, framingRect.top);
                mGriddingPath.lineTo(framingRect.left + i * wUnit, framingRect.bottom);
            }
            for (int i = 0; i <= mGriddingDensity; i++) {
                mGriddingPath.moveTo(framingRect.left, framingRect.top + i * hUnit);
                mGriddingPath.lineTo(framingRect.right, framingRect.top + i * hUnit);
            }
            mFrameHeight = framingRect.bottom - framingRect.top;
        }
        if (mLinearGradientGridding == null) {
            mLinearGradientGridding = new LinearGradient(0, framingRect.top, 0, framingRect.bottom, new int[]{mScaneGridColor, mScaneGridColor, Color.TRANSPARENT}, new float[]{0, 0.99f, 1f}, Shader.TileMode.CLAMP);
            mScanMatrix.setTranslate(0, -mFrameHeight);
            mLinearGradientGridding.setLocalMatrix(mScanMatrix);
            mGriddingPaint.setShader(mLinearGradientGridding);
        }
    }
}
